
package orca;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public abstract class OrcaContext
{
	public static final String FONT_TYPE = "courier new";
	public static final Color BACKGROUND = Color.BLACK;
	public static final Color FOREGROUND = Color.GREEN;

	private final Frame frame;

	private final GraphicsEnvironment gEnv;
	private final GraphicsDevice gDev;
	private final GraphicsConfiguration gConf;

	private final MouseListener mouseListener;
	private final OrcaPane rootPane;

	private Image offscreen = null;

	public OrcaContext()
	{

		this.gEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
		this.gDev = this.gEnv.getDefaultScreenDevice();
		this.gConf = this.gDev.getDefaultConfiguration();

		this.mouseListener = new MouseList();

		this.frame = new Frame(gConf);
		this.frame.setUndecorated(true);
		this.frame.setIgnoreRepaint(true);

		this.frame.addMouseListener(this.mouseListener);

		this.rootPane = new OrcaPane();
		this.rootPane.name = "root";
	}

	public void show()
	{
		int width;
		int height;

		this.gDev.setFullScreenWindow(this.frame);

		width = this.frame.getWidth();
		height = this.frame.getHeight();

		this.offscreen = this.frame.createImage(width, height);

		this.consolidateTree();
	}

	public void refresh()
	{
		Graphics2D painter;
		Graphics display;
		int width = this.frame.getWidth();
		int height = this.frame.getHeight();

		// Paint
		painter = (Graphics2D) this.offscreen.getGraphics();

		this.rootPane.refresh(painter);

		System.out.println("drawing");
		this.paint(painter, width, height);

		// Show
		display = this.frame.getGraphics();
		display.drawImage(this.offscreen, 0, 0, null);

		painter.dispose();
	}

	public void hide()
	{
		this.offscreen = null;

		this.gDev.setFullScreenWindow(null);
	}

	public void exit()
	{
		System.exit(0);
	}

	public void add(OrcaComponent component)
	{
		System.out.println("add");
		this.rootPane.add(component);
	}

	public void consolidateTree()
	{
		this.rootPane.setBounds(0, 0, this.frame.getWidth() - 1, this.frame.getHeight() - 1);
	}

	public abstract void paint(Graphics2D g2d, int width, int height);

	public abstract void mouseClicked(int button, int x, int y);

	public abstract void mousePressed(int button, int x, int y);

	public abstract void mouseReleased(int button, int x, int y);

	private class MouseList implements MouseListener
	{
		@Override
		public void mouseClicked(MouseEvent e)
		{
			Point p = e.getPoint();
			int button = e.getButton();

			OrcaContext.this.mouseClicked(button, p.x, p.y);
			OrcaContext.this.rootPane.mouseClicked(button, p.x, p.y);
		}

		@Override
		public void mousePressed(MouseEvent e)
		{
			Point p = e.getPoint();
			int button = e.getButton();

			OrcaContext.this.mousePressed(button, p.x, p.y);
			OrcaContext.this.rootPane.mousePressed(button, p.x, p.y);
		}

		@Override
		public void mouseReleased(MouseEvent e)
		{
			Point p = e.getPoint();
			int button = e.getButton();

			OrcaContext.this.mouseReleased(button, p.x, p.y);
			OrcaContext.this.rootPane.mouseReleased(button, p.x, p.y);
		}

		@Override
		public void mouseEntered(MouseEvent e)
		{
		}

		@Override
		public void mouseExited(MouseEvent e)
		{
		}
	}
}
